package com.droid.lib.controls.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.droid.lib.controls.R;
import com.droid.lib.controls.util.DragViewUtil;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * Created by ZX on 2017/8/23.
 */

public class SvgView extends View {

    private int[] mstrColorArray = new int[]{R.color.color_svg_map_bg1, R.color.color_svg_map_bg2, R.color.color_svg_map_bg3, R.color.color_svg_map_bg4};

    private Context mContext;
    private Paint mPaint;
    private int mintSvgMap;

    /**
     * 地图区域数组
     */
    private List<MapRegion> mlistMapRegion;
    /**
     * 选中的地图区域
     */
    private MapRegion selectItem;
    /**
     * 缩放比例
     */
    private float mflScale = 0f;
    private float mflShowScale = (float) 2;
    private float mapWidth = 773.0f, mapHeight = 568.0f;
    private AttributeSet attrs;
    private int mintMapColor1;
    private int mintMapColor2;
    private int mintMapColor3;
    private int mintMapColor4;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SvgView(Context context) {
        this(context, null);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SvgView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
        this.attrs = attrs;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SvgView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
        this.attrs = attrs;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SvgView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.attrs = attrs;
        init(context);
    }

    private void init(Context context) {
        final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.SvgView);
        mintSvgMap = attributes.getResourceId(R.styleable.SvgView_dateAddress, R.raw.china_svg);
        mintMapColor1 = attributes.getResourceId(R.styleable.SvgView_dateMapColor1, R.color.color_svg_map_bg1);
        mintMapColor2 = attributes.getResourceId(R.styleable.SvgView_dateMapColor2, R.color.color_svg_map_bg2);
        mintMapColor3 = attributes.getResourceId(R.styleable.SvgView_dateMapColor3, R.color.color_svg_map_bg3);
        mintMapColor4 = attributes.getResourceId(R.styleable.SvgView_dateMapColor4, R.color.color_svg_map_bg4);
        mflShowScale = attributes.getFloat(R.styleable.SvgView_dateShowScale, (float) 2);
        mstrColorArray = new int[]{mintMapColor1, mintMapColor2, mintMapColor3, mintMapColor4};
        this.mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mlistMapRegion = new ArrayList<>();
        threadRun();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        mflScale = (Math.min(width / mapWidth, height / mapHeight) / mflShowScale);

    }

    /**
     * 设置该控件的状态
     *
     * @param colorArray 四个层次的颜色
     */
    public void setColorArray(int[] colorArray) {
        this.mstrColorArray = colorArray;
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mlistMapRegion != null) {
            canvas.scale(mflScale, mflScale);
            for (MapRegion item : mlistMapRegion) {
                if (item != selectItem) {
                    item.draw(canvas, mPaint, false);
                }
            }
            if (selectItem != null) {
                selectItem.draw(canvas, mPaint, true);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mlistMapRegion != null) {
            MapRegion provice = null;
            for (MapRegion item : mlistMapRegion) {
                if (item.isSelect((int) (event.getX() / mflScale), (int) (event.getY() / mflScale))) {
                    provice = item;
                    break;
                }
            }
            if (provice != null) {
                selectItem = provice;
                if (onProvinceSelectedListener != null) {
                    onProvinceSelectedListener.onProvinceSelected(selectItem);
                }
                postInvalidate();
            }
        }
        return true;
    }

    private void threadRun() {
        InputStream inputStream = mContext.getResources().openRawResource(mintSvgMap);
        try {
            //取得 DocumentBuilderFactory 实例
            NodeList items = DragViewUtil.getElementFromPath(inputStream).getElementsByTagName("path");
            for (int i = 0; i < items.getLength(); i++) {

                Element element = (Element) items.item(i);
                String pathData = element.getAttribute("android:pathData");
                Path path = PathParser.createPathFromPathData(pathData);
                mlistMapRegion.add(new MapRegion(path));

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (int i = 0; i < mlistMapRegion.size(); i++) {
            int color;
            int flag = i % 4;
            switch (flag) {
                case 1:
                    color = mstrColorArray[0];
                    break;
                case 2:
                    color = mstrColorArray[1];
                    break;
                case 3:
                    color = mstrColorArray[2];
                    break;
                default:
                    color = mstrColorArray[3];
                    break;
            }
            mlistMapRegion.get(i).setDrawColor(ContextCompat.getColor(getContext(), color));
        }
        postInvalidate();
    }

    public void setNewData(int svgMapId, float scale) {
        invalidate();
        mintSvgMap = svgMapId;
        mlistMapRegion.clear();
        mflShowScale = scale;
        mflScale = (float) 1 / mflShowScale;
        threadRun();
    }

    public interface OnProvinceSelectedListener {
        void onProvinceSelected(MapRegion region);
    }

    private SvgView.OnProvinceSelectedListener onProvinceSelectedListener;

    public void setOnProvinceSelectedListener(SvgView.OnProvinceSelectedListener pOnProvinceSelectedListener) {
        this.onProvinceSelectedListener = pOnProvinceSelectedListener;
    }

    public List<MapRegion> getMlistMapRegion() {
        return mlistMapRegion;
    }

    public void setMlistMapRegion(List<MapRegion> mlistMapRegion) {
        this.mlistMapRegion = mlistMapRegion;
    }
}
